/**
 * Copyright (c) 2018 qar All rights reserved.
 * <p>
 * https://www.qar.io
 * <p>
 * 版权所有，侵权必究！
 */

package com.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.example.constant.Constant;
import com.example.dao.SysRoleDao;
import com.example.dto.SysQueryRoleDTO;
import com.example.dto.SysRoleDTO;
import com.example.entity.SysRoleEntity;
import com.example.model.page.PageData;
import com.example.mybatis.enums.DelFlagEnum;
import com.example.mybatis.enums.SuperAdminEnum;
import com.example.mybatis.service.impl.BaseServiceImpl;
import com.example.security.InfoDetail;
import com.example.security.SecurityUser;
import com.example.service.*;
import com.example.utils.ConvertUtils;
import com.example.utils.JsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 角色管理
 *
 * @author Mark sunlightcs@gmail.com
 * @since 1.0.0
 */
@Service
public class SysRoleServiceImpl extends BaseServiceImpl<SysRoleDao, SysRoleEntity> implements SysRoleService {
    @Autowired
    private SysRoleUserService sysRoleUserService;
    @Autowired
    private SysRoleMenuService sysRoleMenuService;
    @Autowired
    private SysRoleDataScopeService sysRoleDataScopeService;
    @Autowired
    private SysDeptService sysDeptService;


    private QueryWrapper<SysRoleEntity> getWrapper(Map<String, Object> params) {
        String name = (String) params.get("name");
        Boolean isSuperTenant = (Boolean) params.get("isSuperTenant");


        QueryWrapper<SysRoleEntity> wrapper = new QueryWrapper<>();

        if (isSuperTenant) {
            wrapper.like(StringUtils.isNotBlank(name), "name", name);
        } else {
            wrapper.like(StringUtils.isNotBlank(name), "t2.name", name);
        }

        // 只显示满足条件的角色，超级租户：所有， 总店：该租户下的所有角色，普通：该门店的角色
        Object tenantId = params.get("tenantId");
        Object storeId = params.get("storeId");
        if (tenantId != null) {
            wrapper.eq("s2.tenant_id", tenantId);
        }
        if (storeId != null) {
            wrapper.eq("t2.store_id", storeId);
        }

        //普通管理员，只能查询所属部门及子部门的数据
//        InfoDetail user = SecurityUser.getUser();
//        if(user.getIsSuperTenant() == SuperAdminEnum.NO.value()) {
//            List<Long> deptIdList = sysDeptService.getSubDeptIdList(user.getDeptId());
//            wrapper.in(deptIdList != null, "dept_id", deptIdList);
//        }

        return wrapper;
    }

    @Override
    public SysRoleDTO get(Long id) {
        SysRoleEntity entity = baseDao.selectById(id);

        return ConvertUtils.sourceToTarget(entity, SysRoleDTO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(SysRoleDTO dto) {
        SysRoleEntity entity = ConvertUtils.sourceToTarget(dto, SysRoleEntity.class);
        entity.setId(snowflake.nextId());
        //保存角色
        insert(entity);

        //保存角色菜单关系
        sysRoleMenuService.saveOrUpdate(entity.getId(), dto.getMenuIdList());

        //保存角色数据权限关系
        sysRoleDataScopeService.saveOrUpdate(entity.getId(), dto.getDeptIdList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysRoleDTO dto) {
        SysRoleEntity entity = ConvertUtils.sourceToTarget(dto, SysRoleEntity.class);

        //更新角色
        updateById(entity);

        //更新角色菜单关系
        sysRoleMenuService.saveOrUpdate(entity.getId(), dto.getMenuIdList());

        //更新角色数据权限关系
        sysRoleDataScopeService.saveOrUpdate(entity.getId(), dto.getDeptIdList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long[] ids) {
        //逻辑删除角色
        logicDelete(ids, SysRoleEntity.class);

        //删除角色用户关系
        sysRoleUserService.deleteByRoleIds(ids);

        //[角色菜单关系、角色数据权限关系]，需要保留，不然逻辑删除就变成物理删除了
    }

    @Override
    public PageData<SysRoleDTO> selectPage(SysQueryRoleDTO sysQueryRoleDTO) {
        Map<String, Object> params = JsonUtils.convertClassToMap(sysQueryRoleDTO);
        InfoDetail user = SecurityUser.getUser();
        Integer isSuperTenant = user.getIsSuperTenant();
        Integer isHeadStore = user.getIsHeadStore();
        params.put("isSuperTenant", isSuperTenant.equals(1));
        if (isSuperTenant.equals(0)) {
            params.put("tenantId", user.getTenantId());
            if (isHeadStore.equals(0)) {
                params.put("storeId", user.getStoreId());
            }
        }

        IPage<SysRoleEntity> page = getPage(params, Constant.CREATE_DATE, false);
        List<SysRoleEntity> list;
        if (isSuperTenant.equals(0)) {
            list = baseDao.selectList(page, getWrapper(params));
        } else {
            list = baseDao.selectRoleList(page, getWrapper(params));
        }
        page.setRecords(list);
        return getPageData(page, SysRoleDTO.class);
    }

    @Override
    public List<SysRoleDTO> list(Map<String, Object> params) {
        InfoDetail user = SecurityUser.getUser();
        Integer isSuperTenant = user.getIsSuperTenant();
        Integer isHeadStore = user.getIsHeadStore();
        params.put("isSuperTenant", isSuperTenant.equals(1));
        if (isSuperTenant.equals(0)) {
            params.put("tenantId", user.getTenantId());
            if (isHeadStore.equals(0)) {
                params.put("storeId", user.getStoreId());
            }
        }

        List<SysRoleEntity> list;
        if (isSuperTenant.equals(0)) {
            list = baseDao.selectList(getWrapper(params));
        } else {
            list = baseDao.selectRoleList(getWrapper(params));
        }
        return ConvertUtils.sourceToTarget(list, SysRoleDTO.class);
    }

}